using GZ.Common.Data;
using Newtonsoft.Json;
using GZ.DB.Repository.GZ_YUENAN_JX_WCS;
using GZ.DB.Entity.GZ_YUENAN_JX_WCS;
using GZ.DB.IRepository.GZ_YUENAN_JX_WCS;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Configuration;
using GZ.Projects.WCS_SVC;
using System.Net.NetworkInformation;
using GZ.Common.Code;

namespace GZ.Projects.WCS_SVC
{

	#region IC01.作业任务创建M

	/// <summary>
	/// wms任务下发接口参数
	/// </summary>
	[Serializable]
	public class ToWmsCreateOrderRequest
	{
		public string requestPk;
		public string contNo;
		public string contType;
		public string trkType;
		public string trkPrty;
		public string frmPos;
		public string toPos;
		public string isFull;
		public string groupNo;
		public string clientCode;
		public DateTime reqTime;

	}
	
	#endregion
	
	#region IC02.作业任务取消C
	/// <summary>
	/// wms取消任务接口参数
	/// </summary>
	[Serializable]
	public class ToWmsCancelOrderRequest
	{
		public string requestPk;
		public string contNo;
		public string clientCode;
		public DateTime ope_time;
	}
	#endregion
	
	#region IC03.堆垛机状态获取G
	[Serializable]
	public class ToWmsGetDvcStateRequest
	{
		public string DVC_NO;
		public string DVC_AREA;
	}


	#endregion


	#region IC04.任务优先级调整

	[Serializable]
	public class ToWmsOrderPriorityRequest
	{
		public string requestPk;
		public string trkPrty;
	}

	#endregion


	#region Response
	/// <summary>
	/// 任务下发、取消任务、修改优先级返回参数
	/// </summary>
	[Serializable]
	public class ToWmsResponseOrderData
	{
		public string code;
		public string msg;
		public string requestPk;
	}
	/// <summary>
	/// 获取堆垛机状态返回参数
	/// </summary>
    [Serializable]
	public class ToWmsStateData
	{
		public string DVC_NO;
		public string IS_USE;
		public string MODE;
	}

	#endregion
	[Serializable]
	public class ToWmsReportRequest
	{
		public string requestPk;
		public string contNo;
		public string noticeType;
		public string Roadway;
		public string groupNo;
		public string curPos;
		public string taskYn;
		public string code;
		public string result;
		public string clientCode;
		public DateTime reqTime;
	}

	[Serializable]
	public class ToWmsReportResponse
	{
		public string code;
		public string msg;
		public string new_locate_no;
		public string requestPk;
	}

	public class WCSTOWMS
	{
		private static string url = ConfigurationManager.AppSettings["WMSTOWCS"];
		public bool FeedInfoToWms(ToWmsReportRequest mainMissionRequest,out string LocateNo, out string errorMsg)
		{
			string msg = $"\r\n[wcs反馈任务信息至wms：Start{DateTime.Now:yyyy/MM/dd HH:mm:ss:fff}";
			LocateNo = null;
			errorMsg = null;
			ToWmsReportResponse response = new ToWmsReportResponse();
			try
			{

				string input = Json.ToJson(mainMissionRequest);
				msg += $"\r\n\t上报json:[{input}]{DateTime.Now:yyyy/MM/dd HH:mm:ss:fff}";
				//string json = new HttpClient().Call(input, url, out errorMsg);
				string json = new HttpClient().Call("POST",input, url, out errorMsg);
				msg += $"\r\n\t收到回复json:[{json}]{DateTime.Now:yyyy/MM/dd HH:mm:ss:fff}";
				response = Json.ToObject<ToWmsReportResponse>(json);
				if (response != null && response.code == "0")
				{
					LocateNo = response.new_locate_no ?? null;
					return true;
				}
				else
				{
					errorMsg = $"{msg},WMS反馈错误信息：{response.msg}";
					return false;
				}
			}
			catch (Exception ex)
			{
				msg += ex.Message;
				return false;
			}
			finally
			{
				msg = msg.Replace('\'', '\"');
				Conn.YNJXLog.Info(1, $"wcs反馈任务信息至wms ", 1, msg);
			}
		}
	}


	public static class ToWmsHandle
	{
		/// <summary>
		/// 任务回复 ToWmsResponseOrderData JSON 文本
		/// </summary>
		private static string BuildResponse(string code, string msg, string requestPk = null)
		{
			// 截断 msg 到 256 字符,系统异常返回值太长，需要截断
			if (!string.IsNullOrEmpty(msg) && msg.Length > 256)
				msg = msg.Substring(0, 256);
			var resp = new ToWmsResponseOrderData
			{
				code = code,
				msg = msg,
				requestPk = requestPk
			};
			return JsonConvert.SerializeObject(resp);
		}
		/// <summary>
		/// 堆垛机设备ip映射
		/// </summary>
		private static readonly Dictionary<string, string> deviceIps = new Dictionary<string, string>()
        {
            ["TC01"] = "127.0.0.1",
            ["TC02"] = "127.0.0.1",
            ["TC03"] = "127.0.0.1",
            ["TC04"] = "127.0.0.1",
            ["TC05"] = "127.0.0.1",
            ["TC06"] = "127.0.0.1",
            ["TC07"] = "127.0.0.1",
            ["TC08"] = "127.0.0.1",
            ["TC09"] = "127.0.0.1",
            ["TC10"] = "127.0.0.1",
            ["TC11"] = "127.0.0.1",
            ["TC12"] = "127.0.0.1",            
            ["TC13"] = "127.0.0.1",
            ["TC14"] = "127.0.0.1",
            ["TC15"] = "127.0.0.1",
            ["TC16"] = "127.0.0.1",            
            ["TC17"] = "127.0.0.1",
            ["TC18"] = "127.0.0.1",
            ["TC19"] = "127.0.0.1",
            ["TC20"] = "127.0.0.1"
        };
		/// <summary>
		/// IC01.作业任务创建M
		/// </summary>
		/// <param name="requestJson"></param>
		/// <returns></returns>
		public static string CreateOrder(string requestJson)
		{
			//var response = new ToWmsResponseOrderData();
			string respJson = string.Empty;
			try
			{
				var request = JsonConvert.DeserializeObject<ToWmsCreateOrderRequest>(requestJson);
				if (request == null)
				{
					return BuildResponse("-1", "收到的json格式不正确");
				}
				MainMissionEntity mission = new MainMissionEntity();
				mission.ORDER_TYPE = "1111";//必填项
				mission.ORDER_NO = "1111";//必填项
				mission.ORDER_TIME = DateTime.Now;//必填项
				mission.MATERIAL_CODE = "1111"; //必填项
				mission.TASK_NO = request.requestPk;
				mission.TRAY_CODE = request.contNo;
				mission.TRAY_TYPE = request.contType;
				switch (request.trkType)
				{
					case "1": mission.TASK_TYPE = "ST_In";break;
					case "2": mission.TASK_TYPE = "ST_Out";break;
					case "3": mission.TASK_TYPE = "ST_Move";break;
					default: mission.TASK_TYPE = "null";break;
				}
				//mission.TASK_TYPE = request.trkType;
				mission.TASK_PRIORITY = int.Parse(request.trkPrty);
				mission.START_POSITION = request.frmPos;
				mission.END_POSITION = request.toPos;
				mission.GROUP_TYPE = request.isFull;
				mission.GROUP_NO = request.groupNo;
				mission.GROUP_LINE = 0; //必填项
				mission.MATERIAL_CODE = "1111"; //必填项
				mission.REVERSE_1 = request.clientCode;
				mission.OPE_TIME = request.reqTime;
				mission.MISSIONSTATE = "Create";
				mission.SYNCFLAG = "S"; //U=未同步，S=同步至WMS系统
				mission.CREATETIME = DateTime.Now;
				mission.MISSIONSTARTTIME = DateTime.Now;
				mission.INTERSTATIONNO = request.frmPos;
				IMainMissionRepository svc = new MainMissionRepository();
				MainMissionEntity repeat = svc.FindEntity(t => t.TASK_NO == request.requestPk);
				if (repeat == null)
				{
					AutoScanApp autosan = new AutoScanApp();
					//判断任务写入数据库是否成功
					bool mainbl = autosan.ADDMainMissionTask(mission, out string mainessmage);
					if (mainbl)
					{
						return BuildResponse("0", "success",request.requestPk);
						
					}
					else
					{
						return BuildResponse("-1", "任务写入数据库失败",request.requestPk);
					}
				}
				else
				{
					return BuildResponse("-1", "任务编号重复",request.requestPk);
				}
			}

			catch (Exception ex)
			{
				return BuildResponse("-1", ex.Message);
			}

		}
		
		/// <summary>
		/// IC02.作业任务取消M
		/// </summary>
		/// <param name="requestJson"></param>
		/// <returns></returns>
		public static string CancelTask(string requestJson)
		{
			//var response = new ToWmsResponseOrderData();
			string respJson = string.Empty;
			try
			{
				var request = JsonConvert.DeserializeObject<ToWmsCancelOrderRequest>(requestJson);
				if (request == null)
				{
					return BuildResponse("-1", "收到的json格式不正确");
				}


				IMainMissionRepository svc = new MainMissionRepository();
				MainMissionEntity missionET = svc.FindEntity(t => t.TASK_NO == request.requestPk && t.TRAY_CODE == request.contNo );
				if (missionET == null)
				{
					//不存在请求取消的任务号				
					return BuildResponse("-1", "任务表不存在请求的rpk和托盘号",request.requestPk);
				}
				else
				{
					if (missionET.MISSIONSTATE == "Send" || missionET.MISSIONSTATE == "Doing")
					{
						//任务已执行，无法取消
						return BuildResponse("-1", "任务已执行，请在设备上取消任务",request.requestPk);
					}
					else if (missionET.MISSIONSTATE == "Finish")
					{
						//任务已完成，无法取消
						return BuildResponse("-1", $"取消任务失败，{request.requestPk}的托盘号：{request.contNo}任务已完成！",request.requestPk);
					}
					else if (missionET.MISSIONSTATE == "Cancel")
					{

						//任务已执行，无法取消
						return BuildResponse("-1", $"取消任务失败，{request.requestPk}的托盘号：{request.contNo}任务已取消！",request.requestPk);
					}
					
					missionET.MISSIONSTATE = "Cancel";
					AutoScanApp autosan = new AutoScanApp();
					
					bool mainbl = autosan.UPMainMissionTask(missionET, out string mainmsg);	
					if (mainbl)
					{
						return BuildResponse("0", $"取消任务成功，{request.requestPk}的托盘号：{request.contNo}任务被取消！",request.requestPk);					
					}
					else
					{
						return BuildResponse("-1", $"取消任务失败，任务号{request.requestPk}更新数据库失败{mainmsg}！",request.requestPk);	
					}
					
				}				

			}
			catch (Exception ex)
			{
				return BuildResponse("-1", ex.Message);
			}

		}


		/// <summary>
		/// IC03.堆垛机状态获取
		/// </summary>
		/// <param name="requestJson"></param>
		/// <returns></returns>
		public static string GetDvcState(string requestJson)
		{
			var response = new ToWmsStateData();
			string respJson = string.Empty;
			string isUse = string.Empty;
			try
			{
				var request = JsonConvert.DeserializeObject<ToWmsGetDvcStateRequest>(requestJson);
            	//1. 通过字典索引获取 IP
            	string ip = deviceIps[request.DVC_NO];

				//2. 将dvcNo的变量redis名称拿出来
				string dvcNo = request.DVC_NO.StartsWith("TC") ? $"PLC_Stacker{request.DVC_NO.Substring(2)}" : request.DVC_NO;
				Ping ping = new Ping();
				PingReply reply = ping.Send(ip, 120);
				string mode = Conn.Redis.GetValue($"{dvcNo}.dev_vanState") ?? "0";
        		string error = Conn.Redis.GetValue($"{dvcNo}.dev_error")  ?? "1";
        		//3. 判断传过来的堆垛机ip是否在线、无报警、工作模式在在线
			    if (reply.Status == IPStatus.Success && mode == "1" && error == "0")
        		{
			    	isUse="1";
        		}
        		else
        		{
					isUse="0";
        		}		
					response.DVC_NO = request.DVC_NO;
					response.IS_USE = isUse;
					response.MODE = "0"; //暂时无法给出，默认为0
					respJson = JsonConvert.SerializeObject(response);
					return respJson;					
			}				
			catch (Exception ex)
			{
				response.DVC_NO = null;
				response.IS_USE = ex.Message;
				response.MODE = "0";//暂时无法给出，默认为0
				respJson = JsonConvert.SerializeObject(response);
				return respJson;
			}
		}

		/// <summary>
		/// IC04.修改优先级
		/// </summary>
		/// <param name="requestJson"></param>
		/// <returns></returns>
		public static string modifyPriority(string requestJson)
		{
			var response = new ToWmsResponseOrderData();
			string respJson = string.Empty;
			try
			{
				var request = JsonConvert.DeserializeObject<ToWmsOrderPriorityRequest>(requestJson);
				if (request == null)
				{
					return BuildResponse("-1", "收到的json格式不正确");
				}
				else 
				{
					MainMissionEntity mainEt = new MainMissionEntity();
					IMainMissionRepository mainRepo = new MainMissionRepository();

					//1.查主任务是否为出库并且确认堆垛机任务是否已经执行了
					//note:
					//2.可能存在出库任务还没分解，需要确定主任务的状态
					mainEt = mainRepo.FindEntity(t => t.TASK_NO == request.requestPk && t.TASK_TYPE == "ST_Out" && (t.MISSIONSTATE != "Finish" || t.MISSIONSTATE != "Cancel"));
					if(mainEt != null)
					{
						StackerTaskEntity stackEt = new StackerTaskEntity();
						IStackerTaskRepository stackRepo = new StackerTaskRepository();
						stackEt = stackRepo.FindEntity(t => t.TASKNO == request.requestPk && (t.TASKSTATE == "Create" || t.TASKSTATE == "Pre" ));
						if(stackEt != null)
						{
							AutoScanApp autosan = new AutoScanApp();
							stackEt.PRIORITYLEVEL = int.Parse(request.trkPrty);
							mainEt.TASK_PRIORITY = int.Parse(request.trkPrty);
							bool result = autosan.UpdateStackerAndMainTask(stackEt,mainEt, out string mainmsg);	
							if(result)
							{
								return BuildResponse("0", "success",request.requestPk);
							}
							else
							{
								return BuildResponse("-1", $"优先级调整失败，任务号{request.requestPk}更新数据库失败{mainmsg}！",request.requestPk);	
							}
								
						}
					}
					return BuildResponse("-1", "优先级调整失败，任务状态校验失败",request.requestPk);
				}

			}
			catch (Exception ex)
			{
				return BuildResponse("-1", ex.Message);
			}
		}

	}
}